from typing import Optional, List
from fastapi import HTTPException, Depends
from sqlalchemy.orm import Session
from app.models.user import User, UserCreate, UserUpdate, UserModel
from app.database.database import Database
from app.config.database import get_db
from app.config.logger import logger
from app.utils.security import get_password_hash, verify_password, create_access_token
from datetime import timedelta
from app.config.settings import settings

class UserService:
    def __init__(self, db: Session):
        self.db = Database(db)

    def get_user_by_email(self, email: str) -> Optional[UserModel]:
        return self.db.query(UserModel).filter(UserModel.email == email).first()

    def get_user_by_username(self, username: str) -> Optional[UserModel]:
        return self.db.query(UserModel).filter(UserModel.username == username).first()

    def create_user(self, user: UserCreate) -> User:
        # 检查邮箱是否已存在
        if self.get_user_by_email(user.email):
            raise HTTPException(status_code=400, detail="Email already registered")
        
        # 检查用户名是否已存在
        if self.get_user_by_username(user.username):
            raise HTTPException(status_code=400, detail="Username already taken")

        # 创建新用户
        db_user = UserModel(
            username=user.username,
            email=user.email,
            hashed_password=get_password_hash(user.password),
            is_active=True
        )
        self.db.add(db_user)
        self.db.commit()
        self.db.refresh(db_user)
        return db_user

    def authenticate_user(self, username: str, password: str) -> Optional[User]:
        user = self.get_user_by_username(username)
        if not user:
            return None
        if not verify_password(password, user.hashed_password):
            return None
        return user

    def create_access_token_for_user(self, user: User) -> str:
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        return create_access_token(
            data={"sub": user.username},
            expires_delta=access_token_expires
        )

    def get_user(self, user_id: int) -> User:
        user = self.db.query(UserModel).filter(UserModel.id == user_id).first()
        if not user:
            raise HTTPException(status_code=404, detail="User not found")
        return user

    def update_user(self, user_id: int, user_update: UserUpdate) -> User:
        db_user = self.get_user(user_id)
        
        # 如果更新用户名，检查是否已存在
        if user_update.username and user_update.username != db_user.username:
            if self.get_user_by_username(user_update.username):
                raise HTTPException(status_code=400, detail="Username already taken")
        
        # 如果更新邮箱，检查是否已存在
        if user_update.email and user_update.email != db_user.email:
            if self.get_user_by_email(user_update.email):
                raise HTTPException(status_code=400, detail="Email already registered")

        # 更新用户信息
        for key, value in user_update.dict(exclude_unset=True).items():
            if key == "password":
                setattr(db_user, "hashed_password", get_password_hash(value))
            else:
                setattr(db_user, key, value)

        self.db.commit()
        self.db.refresh(db_user)
        return db_user

    def delete_user(self, user_id: int) -> None:
        user = self.get_user(user_id)
        self.db.delete(user)
        self.db.commit()

def get_user_service(db: Session = Depends(get_db)) -> UserService:
    return UserService(db) 